package com.koron.common.core.util.qywx;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName QywxUtil
 * @description
 * @Author zhouj
 * @Date 2021/11/30 17:21
 */
@Slf4j
@Component
public class QywxUtil {

    /*private static String corpId = "ww9a19bad08d912c5f";
    private static String corpSecret = "2T4DlSidvvwcxAy-NnQsyT96GrErmfJL97yPTSHHWYg";

    private static String getToken = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
    private static String jscode2session = "https://qyapi.weixin.qq.com/cgi-bin/miniprogram/jscode2session";
    */

    @Autowired
    QywxProperties qywxProperties;

    @Autowired
    RedisTemplate<String,String> redisTemplate;

    public static CacheTokenBean cacheTokenBean = new CacheTokenBean();

    /**
     * 获取企业微信token
     *
     * @return
     * @throws Exception
     */
    public synchronized String getCacheToken() {

        Date currentTime = new Date();
        Date pastTime = cacheTokenBean.getCacheDate();
        if (pastTime != null) {
            long diff = currentTime.getTime() - pastTime.getTime();
            long min = diff / (1000 * 60);
            //官方2小时过期
            if (min < 100 && StringUtils.isNotEmpty(cacheTokenBean.getCacheToken())) {
                log.info("使用缓存token：{}，时间：{}", cacheTokenBean.getCacheToken(), cacheTokenBean.getCacheDate());
                return cacheTokenBean.getCacheToken();
            }
        }

        try {
            cacheTokenBean.setCacheToken(getToken());
            cacheTokenBean.setCacheDate(currentTime);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        log.info("刷新缓存token：{}，时间：{}", cacheTokenBean.getCacheToken(), cacheTokenBean.getCacheDate());
        return cacheTokenBean.getCacheToken();

    }

    public synchronized static void clearToken() {
        cacheTokenBean = new CacheTokenBean();
    }

    public String getToken() {
        Map<String, String> cond = new HashMap<>();
        cond.put("corpid", qywxProperties.getCorpId());
        cond.put("corpsecret", qywxProperties.getCorpSecret());
        String res = HttpclientUtil.doGet(qywxProperties.getTokenUrl(), cond);
        log.info("获取企业微信access_token", res);
        JSONObject jsonObject = JSONObject.parseObject(res);
        int errcode = jsonObject.getIntValue("errcode");
        if (errcode == 0) {
            return jsonObject.getString("access_token");
        }
        return null;
    }

    /**
     * 区分小程序token
     * @return
     */
    public String getQYWXToken(){

        String qywxTokenKey = "qywx:token";

        String access_token = redisTemplate.opsForValue().get(qywxTokenKey);
        if (StringUtils.isNotBlank(access_token)){
            return access_token;
        }else {
            Map<String, String> cond = new HashMap<>();
            cond.put("corpid", qywxProperties.getCorpId());
            cond.put("corpsecret", qywxProperties.getQYWXCorpIdSecret());
            String res = HttpclientUtil.doGet(qywxProperties.getTokenUrl(), cond);
            log.info("获取企业微信access_token", res);
            JSONObject jsonObject = JSONObject.parseObject(res);
            int errcode = jsonObject.getIntValue("errcode");
            if (errcode == 0) {
                access_token =  jsonObject.getString("access_token");
                redisTemplate.opsForValue().set(qywxTokenKey, access_token, 2, TimeUnit.HOURS);
            }
        }
        return access_token;
    }

    /*
     * 功能描述
     * @author zhouj
     * @date 2022/3/9 16:04
     * @param [access_token, js_code]
     * @return com.alibaba.fastjson.JSONObject
     */
    public JSONObject jscode2session(String access_token, String js_code) {
        Map<String, String> cond = new HashMap<>();
        cond.put("access_token", access_token);
        cond.put("js_code", js_code);
        cond.put("grant_type", "authorization_code");
        String res = HttpclientUtil.doGet(qywxProperties.getJscode2sessionUrl(), cond);
        return JSONObject.parseObject(res);
    }

    public JSONObject getUserInfo(String code){
        Map<String, Object> params = new HashMap<>();
        params.put("access_token", getQYWXToken());
        params.put("code", code);

        String res = HttpclientUtil.doGet(qywxProperties.getUserInfo(), params);
        return JSONObject.parseObject(res);
    }

    public String getJsTicket(){
        String qywxJsTicket = "qywx:jsTicket";
        String ticket = redisTemplate.opsForValue().get(qywxJsTicket);
        if (StrUtil.isNotBlank(ticket)){
            return ticket;
        }

        Map<String,Object> params = new HashMap<>();
        params.put("access_token", getQYWXToken());
        String res = HttpclientUtil.doGet(qywxProperties.getJsTicket(), params);

        JSONObject jsonObject = JSONObject.parseObject(res);
        if (Objects.nonNull(jsonObject) && jsonObject.getInteger("errcode").equals(0)){
            ticket = (String) jsonObject.get("ticket");
            redisTemplate.opsForValue().set(qywxJsTicket, ticket, 2, TimeUnit.HOURS);
        }

        return ticket;
    }
}
